package middleware

import (
	"base-web/api/reponse"
	"bytes"
	"encoding/json"
	"github.com/gin-gonic/gin"
	"github.com/lexkong/log"
	"github.com/willf/pad"
	"io/ioutil"
	"time"
)

type bodyLogWriter struct {
	gin.ResponseWriter
	body *bytes.Buffer
}

func (w bodyLogWriter) Write(b []byte) (int, error) {
	w.body.Write(b)
	return w.ResponseWriter.Write(b)
}

//记录日志
func Logging() gin.HandlerFunc {
	return func(c *gin.Context) {
		start := time.Now().UTC()
		path := c.Request.URL.Path
		var bodyBytes []byte
		if c.Request.Body != nil {
			bodyBytes, _ = ioutil.ReadAll(c.Request.Body)
		}
		// 将io.ReadCloser恢复到原始状态
		c.Request.Body = ioutil.NopCloser(bytes.NewBuffer(bodyBytes))
		method := c.Request.Method
		ip := c.ClientIP()

		blw := &bodyLogWriter{
			body:           bytes.NewBufferString(""),
			ResponseWriter: c.Writer,
		}
		c.Writer = blw

		//继续
		c.Next()

		//记录请求完成后的日志
		//计算请求结束时间
		end := time.Now().UTC()
		latency := end.Sub(start)

		//获取code和message
		var r reponse.Response

		if err := json.Unmarshal(blw.body.Bytes(), &r); err != nil {
			log.Errorf(err, "response body can not unmarshal to global.reponse.Response struct, body: `%s`", blw.body.Bytes())
		}
		dataJson, err := json.Marshal(r.Data)
		if err != nil {
			log.Errorf(err, "response Data to json err : %s", err.Error())
		}
		log.Infof("%-13s | %-12s | %s %s |response: {'code': '%d', 'message': '%s' , 'data': %s }", latency, ip, pad.Right(method, 5, ""), path, r.Code, r.Msg, dataJson)
	}
}
